package com.wsoft.system.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.wsoft.core.cmd.SessionInstanceService;
import com.wsoft.core.exception.Asserts;
import com.wsoft.entity.BaseEntity;
import com.wsoft.hr.pm.service.sys.IHrMemberOrgRelationService;
import com.wsoft.service.IMemberCacheService;
import com.wsoft.service.IMemberCommonService;
import com.wsoft.system.entity.*;
import com.wsoft.system.service.*;
import com.wsoft.vo.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;


/**
 * 功能描述
 *
 * @author: juiet
 * @date: 2024年09月03日 10:37
 */
@Service
public class MemberCommonServiceImpl implements IMemberCommonService {
    public static final Logger logger = LoggerFactory.getLogger(MemberCommonServiceImpl.class);
    @Resource
    private IMemberCacheService memberCacheService;
    @Resource
    private ISysMemberService sysMemberService;
    @Resource
    private ISysAccountService sysAccountService;
    @Resource
    private ISysMemberOrgRoleRelationService sysMemberOrgRoleRelationService;
    @Resource
    private ISysRoleMenuRelationService roleMenuRelationService;
    @Resource
    private ISysMenuResourceRelationService menuResourceRelationService;
    @Resource
    private ISysRoleService sysRoleService;
    @Resource
    private IHrMemberOrgRelationService hrMemberOrgRelationService;

    @Autowired(required = false)
    private List<SessionInstanceService> sessionInstanceServices;

    @Override
    public UserDetails loadUserByUsername(String username) {
        //1、优先取缓存数据
        LoginUserDetail loginUserDetail = memberCacheService.getCacheUser(username);

        if (loginUserDetail instanceof LoginUserDetail) {
            return loginUserDetail;
        }
        //2、缓存没有就重新数据库查出来
        LambdaQueryWrapper<SysAccountEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysAccountEntity::getLoginName, username);
        SysAccountEntity sysAccountEntity = sysAccountService.getOne(queryWrapper);
        if (sysAccountEntity == null) {
            return null;
        }
        SysMemberVO sysMemberVO = sysMemberService.getMember(sysAccountEntity.getMemberId());
        LoginUserVO loginUserVO = new LoginUserVO();
        BeanUtils.copyProperties(sysAccountEntity, loginUserVO, "id");
        BeanUtils.copyProperties(sysMemberVO, loginUserVO);
        loginUserVO.setAccountId(sysAccountEntity.getId());

        // 查询角色信息
        List<MemberOrgRoleRespVO> relations = sysMemberOrgRoleRelationService.getRelationByMember(sysMemberVO.getId());
        if (relations.isEmpty()){
            Asserts.fail("[sys.login.role.error]");
        }
        MemberOrgRoleRespVO respVO = relations.stream().filter(e -> e.getOrgId().equals(sysMemberVO.getLoginOrgId())).findFirst().orElse(null);
        List<SysRoleEntity> roleList = new ArrayList<>();
        if (CollUtil.isEmpty(respVO.getRoleIds())){
            Asserts.fail("[sys.login.role.error]");
        }
            respVO.getRoleIds().forEach(e->{
                SysRoleEntity role = sysRoleService.getRole(e);
                roleList.add(role);
            });
            List<RoleVO> roleVOList = roleList.stream()
                    .map(e -> Convert.convert(RoleVO.class, e))
                    .collect(Collectors.toList());
            loginUserVO.setRoles(roleVOList);

        // 查询资源列表
        loginUserDetail = new LoginUserDetail(loginUserVO, new ArrayList<>());
        if (CollUtil.isNotEmpty(roleList)) {
            List<SysMenuEntity> menuList = new ArrayList<>();
            roleList.forEach(e -> {
                List<SysMenuEntity> list = roleMenuRelationService.getMenuListByRoleId(e.getId());
                menuList.addAll(list);
            });
            if (CollUtil.isNotEmpty(menuList)){
                List<Long> menuIds = menuList.stream().map(BaseEntity::getId).collect(Collectors.toList());
                List<SysResourceEntity> resourceList = menuResourceRelationService.getResourceByMenuIds(menuIds);
                List<ResourceVO> collect = resourceList.stream().map(e -> Convert.convert(ResourceVO.class, e)).collect(Collectors.toList());
                loginUserDetail.setResourceList(collect);
            }
        }

        loadSessionInstance(loginUserDetail);

        //3、重新查出来的重新放入缓存
        memberCacheService.cacheMember(loginUserDetail);
        return loginUserDetail;
    }

    /**
     * 注入登录session变量
     * @param loginUserDetail 当前用户信息
     */
    public void loadSessionInstance(LoginUserDetail loginUserDetail){
        //设置登录session内容
        if(sessionInstanceServices!=null && sessionInstanceServices.size()>0){
            for (SessionInstanceService service : sessionInstanceServices) {
                Object object = service.loginInstance(loginUserDetail.getLoginUserVO().getId());
                if(loginUserDetail.getOneSessionVO(object.getClass())!=null){
                    logger.error("同一个类注入多次，请处理："+object.getClass());
                }
                loginUserDetail.setOneSessionVO(object);
            }
        }
    }
}
